import core from '@/core'

// 打开外部链接
const openLink = (link) => {
	if (link) {
		if (window) {
			try {
				window.open(link, '_blank')
			} catch (error) {
				core.showToast('地址错误')
			}
		} else {
			if (core.router.pages.网页) {
				core.router.to('网页', {link})
			} else {
				console.log('没有网页页面')
			}
		}
	} else {
		console.log('没有链接')
	}
}

/**
 * 预览图片
 * data：可以是字符串，字符串数组，对象数组
 * current：默认预览第几个图片
 * imageKey：如果data是对象数组，imageKey表示获取图片的key
 */
const previewImage = (data, current = 0, imageKey = 'url') => {
	const urls = []
	if (typeof(data) === 'string') {
		urls.push(data)
	} else {
		if (Array.isArray(data)) {
			data.map(item => {
				if (typeof(item) === 'string') {
					urls.push(item)
				} else if (item[imageKey]) {
					urls.push(item[imageKey])
				}
			})
		}
	}
	if (urls.length > 0) {
		uni.previewImage({
			urls, current, 
			loop: true
		})
	}
}

/**
 * 自定义css的@keyframes
 * name：动画名称
 * frames：动画内容
 */
const createKeyframesRule = (name, frames) => {
	 // 获取第一个样式表
	const styleSheet = document.styleSheets[0]
	 // 获取第一条规则名称
	// const firstRules = styleSheet.rules || styleSheet.cssRules
	// const ruleName = firstRules[0].name || ''
	// if (ruleName === name) {
	// 	styleSheet.deleteRule(0)
	// }
	// styleSheet.insertRule(frames, 0)
	
	/**
	 * 设置规则cssRule。类似如下
	 * @keyframes moveUp {
	   0% {
	     transform: translateX(0);
	   }
	   100% {
	     transform: translateX(60px);
	   }
	   frames则为： {
		   '0%': {
		     'transform': 'translateX(0)'
		   },
		   '100%': {
		     'transform': 'translateX(60px)'
		   }
	   }
	}
	 */
	// const keyframesRule = styleSheet.insertRule(`@keyframes ${name} {`, styleSheet.cssRules.length)
	var ruleString = `@keyframes ${name} {`
	Object.keys(frames).forEach(key => {
		var properties = frames[key]
		const keyframeRule = ` ${key} { ${Object.entries(properties).map(([prop, value]) => `${prop}: ${value};`).join(' ')} }`
		ruleString += keyframeRule
		// styleSheet.insertRule(keyframeRule, keyframesRule + 1)
	})
	ruleString += ' }'
	styleSheet.insertRule(ruleString, styleSheet.cssRules.length)
}

// 获取对象数组中的第一个内容
const getFirst = (item, keyValue = 'top') => {
	if (item) {
		if (item[keyValue]) {
			if (typeof(item[keyValue]) === 'string') {
				return item[keyValue]
			}
			if (Array.isArray(item[keyValue]) && item[keyValue].length > 0) {
				for (let i = 0; i < item[keyValue].length; i++) {
					if (item[keyValue][i]) {
						return item[keyValue][i]
					}
				}
			}
		}
	}
	return ''
}

/**
 * 创建组件阴影
 * 每一个阴影的属性：https://www.jb51.net/css/957626.html
 * 	h-shadow：必填。水平偏移；
 * 	v-shadow：必填。竖直偏移；
 * 	blur：可选。模糊距离；
 * 	spread：可选。扩散半径；
 * 	color：可选。阴影颜色。默认黑色
 * 	inset：可选。从外层的阴影（开始时）改变阴影内侧阴影
 * 
 * top：上阴影的大小
 * right：右阴影的大小,
 * bottom：下阴影的大小
 * left：左阴影的大小
 * scale：阴影的模糊距离与扩散半径的比值。建议都要大于1
 * color：阴影颜色。可以是数组，分别表示上右下左的阴影颜色
 */
const boxShadow = (top, right, bottom, left, scale = 1, color = 'rgba(0, 0, 0, 0.5)') => {
	const arr = []
	if (typeof(color) === 'string') {
		color = [color]
	}
	
	// 按照上右下左的序号0123来定义
	const getStr = (radius, index) => {
		if (radius === true) {
			radius = 10
		}
		var str = ''
		switch (index){
			case 0: // // 上阴影
				str = `0 -${radius}px`
				break
			case 1: // // 右阴影
				str = `${radius}px 0`
				break
			case 2: // // 下阴影
				str = `0 ${radius}px`
				break
			case 3: // // 左阴影
				str = `-${radius}px 0`
				break
			default:
				break
		}
		if (str) {
			return `${str} ${radius * scale}px -${radius}px ${color.length > index ? color[index] : color[0]}`
		}
		return ''
	}
	
	if (top) {
		arr.push(getStr(top, 0))
	}
	if (right) {
		arr.push(getStr(right, 1))
	}
	if (bottom) {
		arr.push(getStr(bottom, 2))
	}
	if (left) {
		arr.push(getStr(left, 3))
	}
	return {
		'box-shadow': arr.join(',')	
	}
}


/**
 * @param {Object} event阻止冒泡事件
 * 该事件会完全阻隔父组件接收事件
 */
const onStop = (event, callback) => {
	// 经测试下面这行代码写不写无所谓
	event.stopPropagation && event.stopPropagation() // 阻止事件冒泡
	callback && callback(event)
}

// 比较两个对象是否相同
const differFromObject = (obj1, obj2) => {
	const lodash = require('lodash')
	return !lodash.isEqual(obj1, obj2)
}

/**
 * 获取新旧对象的不同点
 */
const paramsFromDifferent = (newVal, oldVal, params = {}) => {
	if (oldVal) {
		if (differFromObject(newVal, oldVal)) {
			newVal && Object.keys(newVal).forEach(key => {
				if (typeof(newVal[key]) === 'object') {
					if (differFromObject(newVal[key], oldVal[key])) {
						params[key] = newVal[key]
					}
				} else {
					if (newVal[key] !== oldVal[key]) {
						params[key] = newVal[key]
					}
				}
			})
			if (Object.keys(params).length > 0) {
				return params
			}
		}
		// 相同
		return undefined
	}
	return newVal
}

// 从数组中显示值对应的内容
const showLabelFromArray = (value, list, nameKey = 'text', valueKey = 'value') => {
	if (list) {
		for (let i = 0; i < list.length; i++) {
			if (list[i][valueKey] === value) {
				return list[i][nameKey]
			}
		}
	}
	return value
}

// 取最小值
const minValue = (arr) => {
	if (arr.length > 0) {
		var res = arr[0]
		for (let i = 1; i < arr.length; i++) {
			if (parseFloat(arr[i]) < parseFloat(res)) {
				res = arr[i]
			}
		}
		return res
	}
	return undefined
}

// 取最大值
const maxValue = (arr) => {
	if (arr.length > 0) {
		var res = arr[0]
		for (let i = 1; i < arr.length; i++) {
			if (parseFloat(arr[i]) > parseFloat(res)) {
				res = arr[i]
			}
		}
		return res
	}
	return undefined
}

/**
 * 尺寸初始化
 * 返回值是数字
 * 默认单位是px
 * upx：数值要除以2
 * px
 * %
 * vh、vw
 * select：要参考的组件
 * instance：参考的组件对象。该值要求比较高，请参考CaImage
 * 如果instance是对象或者字符串，将直接计算
 * 微信小程序计算instance对象时会延迟（而且计算的结果还是0），H5没有延迟。如果是%这种模式，建议提前获取数据instance传数值进来
 */
const initialSize = (size, type = 'width', select = 'div', instance) => {
	if (size) {
		if (typeof(size) === 'number') {
			return size
		}
		if (size.substr(-3) === 'upx') {
			size = parseFloat(size.substr(0, size.length - 3)) || 0
			return size * 0.5
		}
		if (size.substr(-2) === 'px') {
			size = parseFloat(size.substr(0, size.length - 2)) || 0
			return size
		}
		if (size.substr(-2) === 'vw' || size.substr(-2) === 'vh') {
			size = parseFloat(size.substr(0, size.length - 2)) || 0
			size = core.store.device.info[`window${size.substr(-2) === 'vw' ? 'Width' : 'Height'}`] * size * 0.01
			return size
		}
		if (size.substr(-1) === '%') {
			size = parseFloat(size.substr(0, size.length - 1)) || 0
			var res = 0
			if (!instance) {
				instance = getCurrentPages()
				if (instance.length > 0) {
					instance = instance.pop()
					if (instance.$vm) {
						instance = instance.$vm
					}
				}
			}
			if (instance) {
				if (typeof(instance) === 'string') {
					res = parseFloat(instance) || 0
				} else if (typeof(instance) === 'number') {
					res = instance
				} else {
					const query = uni.createSelectorQuery().in(instance)
					query.select(select).boundingClientRect(data => {
						// 微信小程序走这一步会延迟，H5没有延迟。如果是100%这种，建议提前获取数据instance传数值寄来
						if (data) {
							if (type === 'size') {
								res = minValue([data.width || 0, data.height || 0])
							} else {
								res = data[type] || 0
							}
						}
					}).exec()
				}
				res = res * size * 0.01
			}
			return res
		}
		size = parseFloat(size) || 0
		return size
	}
	return undefined
}

/**
 * 判断该字符是否半角字符
 * 代码来自于DeepSeek
 * Ａ：全角字符
 * A：半角字符
 */
const isHalfWidthChar = (char) => {
    const code = char.charCodeAt(0)
    // 判断是否为半角字符
    return (
        (code >= 0x0000 && code <= 0x007F) || // 半角字母、数字、符号
        code === 0x0020 // 半角空格
    )
}

module.exports = {
	// 打开外部链接
	openLink,
	// 预览图片
	previewImage,
	// 创建动画对象
	createKeyframesRule,
	// 获取对象数组中的第一个内容图片
	getFirst,
	// 创建阴影
	boxShadow,
	// 阻止事件冒泡
	onStop,
	// 比较两个对象是否相同
	differFromObject,
	// 获取新旧对象的不同点
	paramsFromDifferent,
	// 显示数组中值对应的内容
	showLabelFromArray,
	// 取最小值和最大值
	minValue, maxValue,
	// 尺寸初始化
	initialSize,
	// 判断是否为半角字符
	isHalfWidthChar
}